package com.tsd.weixin;

import cn.binarywang.wx.miniapp.api.WxMaService;
import com.tsd.core.datasource.DataSourceContextHolder;
import com.tsd.core.utils.FileUtil;
import com.tsd.core.vo.HlpException;
import com.tsd.storage.StorageService;
import com.tsd.system.service.WxSettingService;
import com.tsd.system.vo.MiniappSetting;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import sun.font.FontDesignMetrics;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;

/**
 * @author Hillpool
 */
@Component
public class QrCodeService {
    private static final Logger logger = LoggerFactory.getLogger(QrCodeService.class);
    @Autowired
    private WxMaService wxMaService;
    @Resource
    private WxSettingService wxSettingService;
    @Autowired
    private StorageService storageService;


    /**
     * 创建对象的分享图
     *
     * @param shareUserId
     * @param objType
     * @param objId
     * @param objName
     * @param pageUrl
     * @return
     */
    public String createImageQrCodeWithName(Integer shareUserId, String objType, String objId, String objName, String pageUrl) throws Exception {
        FileInputStream inputStream = null;
        try {
            String accountSetSid = DataSourceContextHolder.getDataSourceType();
            MiniappSetting miniappSetting = wxSettingService.getWxMiniappSetting();
            if (miniappSetting == null) {
                throw new HlpException("未配置小程序参数");
            }
            wxMaService.setWxMaConfig(miniappSetting.initWxMiniappConfig());
            String scene = objType + "," + objId;
            if (shareUserId != null) {
                scene = scene + ",user," + shareUserId;
            }
            File file = wxMaService.getQrcodeService().createWxaCodeUnlimit(scene, pageUrl);
            inputStream = new FileInputStream(file);
            // 将图片，名字,价格画到模版图中
            byte[] imageData = drawPictureWithName(inputStream, objName);
            ByteArrayInputStream inputStream2 = new ByteArrayInputStream(imageData);
            // 存储分享图
            String url = storageService.store(inputStream2, imageData.length, "image/jpeg", accountSetSid, getKeyName(objType + "_qr", objId));
            logger.info("创建分享图 URL:{}", url);
            return url;
        } finally {
            FileUtil.safeCloseInputStrem(inputStream);
        }
    }

    /**
     * 将商品图片，商品名字画到模版图中
     *
     * @param qrCodeImg 二维码图片
     * @param goodName  商品名称
     * @return
     * @throws IOException
     */
    private byte[] drawPictureWithName(InputStream qrCodeImg, String goodName) throws IOException {
        ByteArrayOutputStream bs = new ByteArrayOutputStream();
        // 小程序二维码
        BufferedImage qrCodeImage = ImageIO.read(qrCodeImg);
        int w = qrCodeImage.getWidth();
        int h = qrCodeImage.getHeight();
        int padding = 100;
        // --- 画图 ---
        // 底层空白 bufferedImage
        BufferedImage baseImage = new BufferedImage(w + padding, h + padding, BufferedImage.TYPE_4BYTE_ABGR_PRE);
        //透明背景 the begin
        Graphics2D g = (Graphics2D) baseImage.getGraphics();
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, w + padding, h + padding);
//		baseImage = g.getDeviceConfiguration().createCompatibleImage(w+padding, h+padding, Transparency.TRANSLUCENT);
        //透明背景 the end
        // 画上小程序二维码
        drawImgInImg(baseImage, qrCodeImage, padding / 2, padding / 4, w, h);

        // 写上商品名称,截取前面的12个字符长度
        if (goodName.length() > 12) {
            goodName = goodName.substring(0, 12) + "...";
        }
        Color colorComm = new Color(60, 60, 60);
        drawTextInImgCenterH(baseImage, goodName, w + padding, h + padding / 4, colorComm, 28);
        // 转jpg
        BufferedImage result = new BufferedImage(baseImage.getWidth(), baseImage.getHeight(),
                BufferedImage.TYPE_3BYTE_BGR);
        result.getGraphics().drawImage(baseImage, 0, 0, null);
        ImageIO.write(result, "jpg", bs);
        // 最终byte数组
        return bs.toByteArray();
    }

    @SuppressWarnings("unused")
    private void drawTextInImgCenter(BufferedImage baseImage, String textToWrite, int y) {
        Graphics2D g2D = (Graphics2D) baseImage.getGraphics();
        g2D.setColor(new Color(167, 136, 69));

        String fontName = "Microsoft YaHei";

        Font f = new Font(fontName, Font.PLAIN, 28);
        g2D.setFont(f);
        g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // 计算文字长度，计算居中的x点坐标
        FontMetrics fm = g2D.getFontMetrics(f);
        int textWidth = fm.stringWidth(textToWrite);
        int widthX = (baseImage.getWidth() - textWidth) / 2;
        // 表示这段文字在图片上的位置(x,y) .第一个是你设置的内容。

        g2D.drawString(textToWrite, widthX, y);
        // 释放对象
        g2D.dispose();
    }

    public static int getWordWidth(Font font, String content) {
        FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
        int width = 0;
        for (int i = 0; i < content.length(); i++) {
            width += metrics.charWidth(content.charAt(i));
        }
        return width;
    }

    private void drawTextInImgCenterH(BufferedImage baseImage, String textToWrite, int width, int y, Color color, int fontSize) {
        Graphics2D g2D = (Graphics2D) baseImage.getGraphics();
        g2D.setColor(color);

        Font font = new Font("Microsoft YaHei", Font.PLAIN, fontSize);
        g2D.setFont(font);
        int ww = getWordWidth(font, textToWrite);
        int x = (width - ww) / 2;
        FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
        int fontHeight = metrics.getHeight();
        g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        //文字输出距离图片10个像素
        y = y + fontHeight + 10;
        g2D.drawString(textToWrite, x, y);
        g2D.dispose();
    }

    private void drawImgInImg(BufferedImage baseImage, BufferedImage imageToWrite, int x, int y, int width,
                              int heigth) {
        Graphics2D g2D = (Graphics2D) baseImage.getGraphics();
        g2D.drawImage(imageToWrite, x, y, width, heigth, null);
        g2D.dispose();
    }

    /**
     * 分享二维码图片在OSS上面的名称
     *
     * @param keyType
     * @param id
     * @return
     */
    private String getKeyName(String keyType, String id) {
        return DataSourceContextHolder.getDataSourceType() + "/" + keyType + "/" + id + ".jpg";
    }
}
